package com.example.demo.common;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.common.constant.HttpFlag;
import com.example.demo.common.constant.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

@Slf4j
public class Http {
    // 发起Post访问（指定参数名的Map型数据）
    public static String post(String apiUrl, JSONObject param, JSONObject header, String paramType, String returnType) {
        String result = "";
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;

        try {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            ContentType strContent = ContentType.create("text/plain", StandardCharsets.UTF_8);

            //填充请求头
            HttpPost httpPost = new HttpPost(apiUrl);
            if (header != null) {
                for (String key : header.keySet()) {
                    httpPost.setHeader(key, header.getString(key));
                }
            }

            //填充参数
            if (paramType == null || paramType.equals(HttpFlag.FORM_DATA)) {
                for (String key : param.keySet()) {
                    builder.addTextBody(key, param.getString(key), strContent);
                }
                org.apache.http.HttpEntity entity = builder.build();
                httpPost.setEntity(entity);
            }
            else if (paramType.equals(HttpFlag.RAW_JSON)) {
                httpPost.setEntity(new StringEntity(param.toJSONString(), StandardCharsets.UTF_8));
            }

            /*RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
            CookieStore cookieStore = new BasicCookieStore();
            CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(globalConfig).setDefaultCookieStore(cookieStore).build();
            CloseableHttpClient client = HttpClients.createDefault();
            CloseableHttpResponse response = client.execute(httpPost);*/
            client = HttpClients.createDefault();
            response = client.execute(httpPost);

            //获取常用Cookie,包括_xsrf信息，创建cookie store的本地实例
            /*StringBuffer cookie = new StringBuffer();
            for (Cookie c : cookieStore.getCookies()) {
                cookie.append(c.getName() + "=" + c.getValue() + "。");
            }
            String cookieres = cookie.toString();
            if (cookieres.length() > 0) {
                cookieres = cookieres.substring(0, cookieres.length() - 1);
            }*/

            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), "UTF-8");

                if (returnType != null && returnType.equals(HttpFlag.RESPONSE_HEADER)) {
                    StringBuffer sb = new StringBuffer();
                    Header[] cookies = response.getAllHeaders();
                    for (Header cookie : cookies) {
                        sb.append(cookie.getName()).append("=").append(cookie.getValue()).append("。");
                    }
                    String temp = sb.toString().replace("[", "").replace("]", "").replace("path=/,", "").replace("path=/]", "");
                    if (!temp.equals("")) {
                        result += "【@#】" + temp;
                    }
                }
            }
        }
        catch (Exception e1) {
            log.error(ResultCode.HTTP_POST_ERROR.getMessage() + e1.getMessage());
        }
        finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }
            }
            catch (Exception e2) {
                log.error(ResultCode.HTTP_CLOSE_ERROR.getMessage() + e2.getMessage());
            }
        }

        return result;
    }

    // 发起Post访问（不指定参数名的序列化数据）
    public static String post(String apiUrl, String data, JSONObject header, String returnType) {
        StringBuilder result = new StringBuilder();
        HttpURLConnection conn = null;
        BufferedReader br = null;
        InputStream is = null;

        try {
            URL url = new URL(apiUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            //设置30秒连接超时与读取超时
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            //设置是否向httpUrlConnection输出，因为这个是post请求，参数要放在http正文内，因此需要设为true, 默认情况下是false;
            conn.setDoOutput(true);
            //设置是否从httpUrlConnection读入，默认情况下是true;
            conn.setDoInput(true);
            //Post请求不能使用缓存
            conn.setUseCaches(false);
            //设置请求头
            if (header != null) {
                for (String key : header.keySet()) {
                    conn.setRequestProperty(key, header.getString(key));
                }
            }
            //建立连接
            conn.connect();

            //获取URLConnection对象对应的输出流
            //此处getOutputStream会隐含的进行connect(即：如同调用上面的connect()方法，所以在开发中不调用上述的connect()也可以)。
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
            //发送请求参数，即：不指定参数名的序列化数据
            out.write(data);
            out.flush();

            //获取URLConnection对象对应的输入流
            is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is));
            String line = "";
            while ((line = br.readLine()) != null){
                result.append(line);
            }

            if (returnType != null && returnType.equals(HttpFlag.RESPONSE_HEADER)) {
                Map<String, List<String>> map = conn.getHeaderFields();
                if (map.size() > 0) {
                    StringBuffer sb = new StringBuffer();
                    for (Map.Entry entry : map.entrySet()) {
                        if (entry.getKey() != null) {
                            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("。");
                        }
                    }
                    String temp = sb.toString().replace("[", "").replace("]", "").replace("path=/,", "").replace("path=/]", "");
                    if (!temp.equals("")) {
                        result.append("【@#】").append(temp);
                    }
                }
            }

            //关闭流与断开连接
            br.close();
            is.close();
            conn.disconnect();
        }
        catch (Exception e1) {
            log.error(ResultCode.HTTP_POST_ERROR.getMessage() + e1.getMessage());
        }
        finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (is != null) {
                    is.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            }
            catch (Exception e2) {
                log.error(ResultCode.HTTP_CLOSE_ERROR.getMessage() + e2.getMessage());
            }
        }

        return result.toString();
    }

    // 发起Get访问（可指定返回值类型，Get访问主要用这个方法）
    public static String get(String webUrl, JSONObject header, String returnType) {
        String result = "";
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;

        try {
            //填充请求头
            HttpGet httpGet = new HttpGet(webUrl);
            if (header != null) {
                for (String key : header.keySet()) {
                    httpGet.setHeader(key, header.getString(key));
                }
            }

            client = HttpClients.createDefault();
            response = client.execute(httpGet);

            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), "UTF-8");

                if (returnType != null && returnType.equals(HttpFlag.RESPONSE_HEADER)) {
                    StringBuffer sb = new StringBuffer();
                    Header[] cookies = response.getAllHeaders();
                    for (Header cookie : cookies) {
                        sb.append(cookie.getName()).append("=").append(cookie.getValue()).append("。");
                    }
                    String temp = sb.toString().replace("[", "").replace("]", "").replace("path=/,", "").replace("path=/]", "");
                    if (!temp.equals("")) {
                        result += "【@#】" + temp;
                    }
                }
            }
        }
        catch (Exception e1) {
            log.error(ResultCode.HTTP_GET_ERROR.getMessage() + e1.getMessage());
        }
        finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }
            }
            catch (Exception e2) {
                log.error(ResultCode.HTTP_CLOSE_ERROR.getMessage() + e2.getMessage());
            }
        }

        return result;
    }

    // 发起Get访问（老版备份但不用）
    public static String get(String webUrl, JSONObject header) {
        StringBuilder result = new StringBuilder();
        BufferedReader br = null;
        InputStream is = null;

        try {
            URL url = new URL(webUrl);
            // 打开和URL之间的连接
            URLConnection conn = url.openConnection();
            //设置30秒连接超时与读取超时
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            //设置请求头
            if (header != null) {
                for (String key : header.keySet()) {
                    conn.setRequestProperty(key, header.getString(key));
                }
            }
            //建立连接
            conn.connect();

            //获取URLConnection对象对应的输入流
            is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is));
            String line = "";
            while ((line = br.readLine()) != null){
                result.append(line);
            }

            //关闭流与断开连接
            br.close();
            is.close();
        }
        catch (Exception e1) {
            log.error(ResultCode.HTTP_GET_ERROR.getMessage() + e1.getMessage());
        }
        finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (is != null) {
                    is.close();
                }
            }
            catch (Exception e2) {
                log.error(ResultCode.HTTP_CLOSE_ERROR.getMessage() + e2.getMessage());
            }
        }

        return result.toString();
    }
}
